GDD
Tower of light
Game Design Document
The real feel
Table of Contents
in old Arabia a small young boy is caught trying to steal a lamp. But just before he got caught he desperately wished that the guards would not find the lamp. He needed it because he wanted to sell it so he could eat. He was an orphan and had nothing. At that point a mysterious magic from within the lamp fulfilled his wish. And when the guards questioned him he pretended to know nothing. So the guards decided to bring him before the sultan. The boy was told to kneel before him an was asked once again where he had hidden the lamp but he boy stayed silent. This infuriated the sultan and so he decreed the boy would be put at the top of the tower of light until he told him were the lamp was. After a couple of days he herd the guards screaming and running down stairs so the boy decided this to be his best chance to escape.
genre:
action adventure with puzzle elements.
Esthetics:
Fantasy and discovery.
Target audience:
Teens/ young adult
(12 - 25)
Perspective:
Third person.
The game is based in a tower witch is designed in a maze like structure. The top of the tower is light and beautiful and looks like a royal chamber with a lot of gold and expensive thins. the more you get to the bottom the darker the environment gets with a dungeon like esthetic. Set in an Arabic theme
the main character is a small Arabian boy who is very poor but quick an agile
Enemy jinn
Friendly jinn (companion)
guard
sultan: an old man with a big nose, is fat and with royal clothing.
guard
main character
Walking with W, A, S, D.
Jumping with spacebar.
Sprinting with left shift.
Crouching with C.
picking up objects
throwing objects
stun with E (AOE).
interacting with F.
sneaking (crouching)
third person camera that moves around character with the mouse
States static, following, attacking, patrolling, asleep and dead.
Path finding (unity)
3.5other
intro cutscene that shows the story of the game.
Collectible system.
code
enemy AI
using UnityEngine;
using System.Collections;
public class EnemyManager : MonoBehaviour {
//-----------------------------------------------------------------
// -algemeen-
//-----------------------------------------------------------------
public enum states {sleeping, guarding, following, attacking, patrolling, dead};
public states currentstate;
NavMeshAgent agent;
float stunTimer = 10f;
public bool stunned;
//-----------------------------------------------------------------
// -raycast-
//-----------------------------------------------------------------
public Ray myRay;
RaycastHit hit;
//-----------------------------------------------------------------
// -sleeping-
//-----------------------------------------------------------------
bool isAwake;
//-----------------------------------------------------------------
// -guarding-
//-----------------------------------------------------------------
bool rotatedirection;
public int surchrange;
private float distance;
private float derection;
//-----------------------------------------------------------------
// -follow-
//-----------------------------------------------------------------
public GameObject player;
public Transform target;
private float timer;
//-----------------------------------------------------------------
// -patrolling-
//-----------------------------------------------------------------
bool patrolleDerection;
public bool isPatrolling;
int patrolTarget;
private float patroltimer;
public Vector3[] waypoint;
//_____________________________________________________________________
void Start () {
//-----------------------------------------------------------------
// -algemeen-
//-----------------------------------------------------------------
if (isPatrolling) {
currentstate = states.patrolling;
isAwake = true;
} else {
currentstate = states.sleeping;
isAwake = false;
}
agent = this.GetComponent<NavMeshAgent> ();
//-----------------------------------------------------------------
// -sleeping-
//-----------------------------------------------------------------
//-----------------------------------------------------------------
// -guarding-
//-----------------------------------------------------------------
rotatedirection = false;
surchrange = 20;
//-----------------------------------------------------------------
// -patrolling-
//-----------------------------------------------------------------
patrolTarget = 1;
patrolleDerection = true;
}
void Update () {
//----------------------------------------------------------------
// debuging
//----------------------------------------------------------------
//Debug.Log (currentstate);
Debug.Log (derection);
//Debug.Log (waypoint[patrolTarget]);
Debug.Log (patroltimer);
//Debug.DrawRay(transform.position, transform.forward * 50, Color.red );
//----------------------------------------------------------------
// algemeen
//----------------------------------------------------------------
distance = Vector3.Distance (this.gameObject.transform.position, player.transform.position);
if (stunned) {
Stun ();
}
//----------------------------------------------------------------
// raycast
//----------------------------------------------------------------
myRay = new Ray (transform.position, transform.forward);
Physics.Raycast (myRay, out hit, 50f);
if (hit.collider.CompareTag ("Player")) {
target = hit.transform;
}
//----------------------------------------------------------------
// sleeping
//----------------------------------------------------------------
if (timer > 0) {
timer -= Time.deltaTime;
}
if (!isAwake && GameManager.manager.sound > 10)
{
currentstate = states.guarding;
isAwake = true;
}
//----------------------------------------------------------------
//patrolling
//----------------------------------------------------------------
if (patroltimer > 0)
{
patroltimer -= Time.deltaTime;
}
//----------------------------------------------------------------
// switch
//----------------------------------------------------------------
switch (currentstate) {
case states.sleeping:
if (GameManager.manager.sound > 10) {
currentstate = states.guarding;
}
break;
case states.guarding:
stunned = false;
if (hit.collider.CompareTag("Player")) {
currentstate = states.following;
} else {
if (derection > surchrange && derection < surchrange + 10)
{
Debug.Log ("derectionchange to false");
rotatedirection = false;
}
else if (derection < -surchrange && derection > -surchrange - 10)
{
Debug.Log ("derectionchange to true");
rotatedirection = true;
}
if (rotatedirection)
{
this.gameObject.transform.Rotate (transform.up, Time.deltaTime);
derection += Time.deltaTime;
Debug.Log ("rotate+");
}
else
{
this.gameObject.transform.Rotate (-transform.up, Time.deltaTime);
derection -= Time.deltaTime;
Debug.Log ("rotate-");
}
}
break;
case states.following:
gameObject.GetComponent<NavMeshAgent> ().speed = 2;
derection = 0;
Debug.Log ("following triggert");
if (hit.collider.CompareTag ("Player"))
{
Debug.Log ("is following");
agent.destination = target.position;
transform.LookAt (new Vector3 (hit.transform.position.x, transform.position.y, hit.transform.position.z));
if (this.gameObject.transform.position == target.position)
{
currentstate = states.guarding;
}
}
else
{
currentstate = states.guarding;
}
if (distance < 2f && timer <= 0)
{
timer = 5;
GameManager.manager.playerhealth--;
Debug.Log ("is damaging");
}
break;
case states.patrolling:
gameObject.GetComponent<NavMeshAgent> ().speed = 1;
if (patroltimer <= 0)
{
agent.destination = waypoint [patrolTarget];
}
float waypointDistance = Vector3.Distance (waypoint [patrolTarget], transform.position);
if (waypointDistance < 2)
{
patroltimer = 0;
Debug.Log ("blep");
if (patrolleDerection)
{
Debug.Log ("++");
patrolTarget++;
}
else
{
Debug.Log ("--");
patrolTarget--;
}
}
if (patrolTarget == waypoint.Length - 1)
{
patrolleDerection = false;
}
if (patrolTarget == 0)
{
patrolleDerection = true;
}
if (hit.collider.CompareTag("Player"))
{
currentstate = states.following;
}
break;
}
}
void Stun(){
currentstate = states.sleeping;
stunTimer -= Time.deltaTime;
if (stunTimer <= 0) {
stunTimer = 10f;
currentstate = states.guarding;
}
}
public void OnCollisionEnter(Collision other)
{
rotatedirection = !rotatedirection;
}
}
using System.Collections;
public class EnemyManager : MonoBehaviour {
//-----------------------------------------------------------------
// -algemeen-
//-----------------------------------------------------------------
public enum states {sleeping, guarding, following, attacking, patrolling, dead};
public states currentstate;
NavMeshAgent agent;
float stunTimer = 10f;
public bool stunned;
//-----------------------------------------------------------------
// -raycast-
//-----------------------------------------------------------------
public Ray myRay;
RaycastHit hit;
//-----------------------------------------------------------------
// -sleeping-
//-----------------------------------------------------------------
bool isAwake;
//-----------------------------------------------------------------
// -guarding-
//-----------------------------------------------------------------
bool rotatedirection;
public int surchrange;
private float distance;
private float derection;
//-----------------------------------------------------------------
// -follow-
//-----------------------------------------------------------------
public GameObject player;
public Transform target;
private float timer;
//-----------------------------------------------------------------
// -patrolling-
//-----------------------------------------------------------------
bool patrolleDerection;
public bool isPatrolling;
int patrolTarget;
private float patroltimer;
public Vector3[] waypoint;
//_____________________________________________________________________
void Start () {
//-----------------------------------------------------------------
// -algemeen-
//-----------------------------------------------------------------
if (isPatrolling) {
currentstate = states.patrolling;
isAwake = true;
} else {
currentstate = states.sleeping;
isAwake = false;
}
agent = this.GetComponent<NavMeshAgent> ();
//-----------------------------------------------------------------
// -sleeping-
//-----------------------------------------------------------------
//-----------------------------------------------------------------
// -guarding-
//-----------------------------------------------------------------
rotatedirection = false;
surchrange = 20;
//-----------------------------------------------------------------
// -patrolling-
//-----------------------------------------------------------------
patrolTarget = 1;
patrolleDerection = true;
}
void Update () {
//----------------------------------------------------------------
// debuging
//----------------------------------------------------------------
//Debug.Log (currentstate);
Debug.Log (derection);
//Debug.Log (waypoint[patrolTarget]);
Debug.Log (patroltimer);
//Debug.DrawRay(transform.position, transform.forward * 50, Color.red );
//----------------------------------------------------------------
// algemeen
//----------------------------------------------------------------
distance = Vector3.Distance (this.gameObject.transform.position, player.transform.position);
if (stunned) {
Stun ();
}
//----------------------------------------------------------------
// raycast
//----------------------------------------------------------------
myRay = new Ray (transform.position, transform.forward);
Physics.Raycast (myRay, out hit, 50f);
if (hit.collider.CompareTag ("Player")) {
target = hit.transform;
}
//----------------------------------------------------------------
// sleeping
//----------------------------------------------------------------
if (timer > 0) {
timer -= Time.deltaTime;
}
if (!isAwake && GameManager.manager.sound > 10)
{
currentstate = states.guarding;
isAwake = true;
}
//----------------------------------------------------------------
//patrolling
//----------------------------------------------------------------
if (patroltimer > 0)
{
patroltimer -= Time.deltaTime;
}
//----------------------------------------------------------------
// switch
//----------------------------------------------------------------
switch (currentstate) {
case states.sleeping:
if (GameManager.manager.sound > 10) {
currentstate = states.guarding;
}
break;
case states.guarding:
stunned = false;
if (hit.collider.CompareTag("Player")) {
currentstate = states.following;
} else {
if (derection > surchrange && derection < surchrange + 10)
{
Debug.Log ("derectionchange to false");
rotatedirection = false;
}
else if (derection < -surchrange && derection > -surchrange - 10)
{
Debug.Log ("derectionchange to true");
rotatedirection = true;
}
if (rotatedirection)
{
this.gameObject.transform.Rotate (transform.up, Time.deltaTime);
derection += Time.deltaTime;
Debug.Log ("rotate+");
}
else
{
this.gameObject.transform.Rotate (-transform.up, Time.deltaTime);
derection -= Time.deltaTime;
Debug.Log ("rotate-");
}
}
break;
case states.following:
gameObject.GetComponent<NavMeshAgent> ().speed = 2;
derection = 0;
Debug.Log ("following triggert");
if (hit.collider.CompareTag ("Player"))
{
Debug.Log ("is following");
agent.destination = target.position;
transform.LookAt (new Vector3 (hit.transform.position.x, transform.position.y, hit.transform.position.z));
if (this.gameObject.transform.position == target.position)
{
currentstate = states.guarding;
}
}
else
{
currentstate = states.guarding;
}
if (distance < 2f && timer <= 0)
{
timer = 5;
GameManager.manager.playerhealth--;
Debug.Log ("is damaging");
}
break;
case states.patrolling:
gameObject.GetComponent<NavMeshAgent> ().speed = 1;
if (patroltimer <= 0)
{
agent.destination = waypoint [patrolTarget];
}
float waypointDistance = Vector3.Distance (waypoint [patrolTarget], transform.position);
if (waypointDistance < 2)
{
patroltimer = 0;
Debug.Log ("blep");
if (patrolleDerection)
{
Debug.Log ("++");
patrolTarget++;
}
else
{
Debug.Log ("--");
patrolTarget--;
}
}
if (patrolTarget == waypoint.Length - 1)
{
patrolleDerection = false;
}
if (patrolTarget == 0)
{
patrolleDerection = true;
}
if (hit.collider.CompareTag("Player"))
{
currentstate = states.following;
}
break;
}
}
void Stun(){
currentstate = states.sleeping;
stunTimer -= Time.deltaTime;
if (stunTimer <= 0) {
stunTimer = 10f;
currentstate = states.guarding;
}
}
public void OnCollisionEnter(Collision other)
{
rotatedirection = !rotatedirection;
}
}
game manager
using UnityEngine;
using System.Collections;
using UnityEngine.SceneManagement;
public class GameManager : MonoBehaviour {
public static GameManager manager;
public float sound;
public float stunTimer;
public int playerhealth;
public int collectible;
void Awake ()
{
if (manager == null) {
GameManager.manager = this;
DontDestroyOnLoad (gameObject);
}
else
{
Destroy (gameObject);
}
}
// Use this for initialization
void Start () {
stunTimer = 0;
playerhealth = 5;
}
// Update is called once per frame
void Update () {
Debug.Log (playerhealth);
//Debug.Log (playerhealth);
//Debug.Log (collectible);
sound += 0.1f;
if (stunTimer > 0)
{
stunTimer -= Time.deltaTime;
}
if (playerhealth <= 0)
{
SceneManager.LoadScene (1);
}
}
public void damage (){
playerhealth -= 1;
}
}
using System.Collections;
using UnityEngine.SceneManagement;
public class GameManager : MonoBehaviour {
public static GameManager manager;
public float sound;
public float stunTimer;
public int playerhealth;
public int collectible;
void Awake ()
{
if (manager == null) {
GameManager.manager = this;
DontDestroyOnLoad (gameObject);
}
else
{
Destroy (gameObject);
}
}
// Use this for initialization
void Start () {
stunTimer = 0;
playerhealth = 5;
}
// Update is called once per frame
void Update () {
Debug.Log (playerhealth);
//Debug.Log (playerhealth);
//Debug.Log (collectible);
sound += 0.1f;
if (stunTimer > 0)
{
stunTimer -= Time.deltaTime;
}
if (playerhealth <= 0)
{
SceneManager.LoadScene (1);
}
}
public void damage (){
playerhealth -= 1;
}
}